home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Tele / C / Comet2.1.3.cpt / emlib / printf.c < prev    next >
Text File  |  1991-10-28  |  6KB  |  269 lines

  1. /*  Copyright 1984 by the Massachusetts Institute of Technology  */
  2. /*  See permission and disclaimer notice in file "notice.h"  */
  3.  
  4. /*
  5.     Copyright Cornell University 1986.  All rights are reserved.
  6.  
  7.     As of 4/10/86:
  8.     This source file may have no changes from the M.I.T original
  9.     other than this notice; but it has been tested as part of 
  10.     Cornell's Aztec-C port.  See notice.h
  11.  
  12. */
  13.  
  14. /* 9/19/85 kevin - putc() changed to em(); all routine(char, outarg) */
  15. /* 9/20/85 kevin added TRUE & FALSE */
  16. /* 9/20/85 kevin changed for 1-parameter em(char) */
  17. /* 9/2/87 kevin changed some names to make new compiler happy */
  18. /* 9/30/87 kevin removed call to Button() in printf which made mouse menu selects difficult when lots of data being rec'd */
  19. /* 3/18/88 kevin fixed so no \r added if output routine not em() */
  20. /* 3/16/89 kevin fixed to use cu_exit() */
  21. /* 9/26/90 kevin changed em to vt100 */
  22.  
  23. #include    <h19.h> 
  24. #include    <stdio.h>
  25.  
  26. #define TRUE    (-1)
  27. #define FALSE    0
  28.  
  29. #define DOEMOUTPUT
  30. #ifdef DOEMOUTPUT
  31.  
  32. extern vt100();
  33.  
  34. #undef    putchar
  35.  
  36. putchar(thechar)
  37. char thechar;
  38. {
  39.     emprep();
  40.     vt100(thechar);
  41.     emend();
  42. }
  43.  
  44. printf(format)
  45. char    *format; 
  46. {
  47.     emprep();
  48.     _format_string(vt100, stdout, &format);    /* kevin was putc */
  49.     /* 9/20/86 kevin update cursor if done */
  50.     setcursor();
  51.     emend();
  52. }
  53.  
  54. fatal(format)
  55. char *format; 
  56. {
  57.  
  58.     emprep();
  59.     _format_string(vt100, stdout, &format);    /* was putc */
  60.     printf("\n");
  61.     emend();
  62.     cu_exit(1);
  63. }
  64.  
  65. #endif
  66.  
  67. #ifdef REDIRECTABLE
  68. fprintf(fd, format)
  69. FILE    *fd;
  70. char    *format;
  71. {
  72.     _format_string(vt100, fd, &format);    /* was putc */
  73. }
  74. #endif
  75.  
  76. int    store_string();
  77. char    *_sp;            /* this should be not be static since it */
  78.                 /* is used by TCP's printf and others      */
  79.  
  80. sprintf(s, format)
  81. char    *s;
  82. char    *format;
  83. {
  84.     _sp = s;
  85.     _format_string(store_string, NULL, &format);
  86.     *_sp = '\0';
  87. }
  88.  
  89. store_string(c)            /* was (c, foo); int    foo;*/
  90. char    c;
  91. {
  92.     *_sp++ = c;
  93. }
  94.  
  95. /* WARNING--kevin-- this routine will break if char != int on the stack */
  96.  
  97. _format_string(routine, outarg, data)
  98. int    (*routine)();    /* the routine to output the characters */
  99. FILE *    outarg;            /* an argument to pass to the output routine */
  100. char    **data;        /* the address to get the format string and the arguments from */
  101. {
  102.     unsigned *arg;    /* a pointer to the arguments on the stack */
  103.     char    *format;    /* a pointer to the format string */
  104.     int    field;            /* number after a '%' and before the format character */
  105.     int    l_zero;            /* flag is true if the number started with a
  106.                              '0', if so then print out leading zeros */
  107.     char    *s;            /* string pointer for 2nd-nth arguments */
  108.     
  109.     format = *data;
  110.     arg = (unsigned  *) data;
  111.     arg += 2;    /* skip first arg, pointer to format string */
  112. loop:    while ((*format != '%') && (*format != '\0')) {
  113.         /* was (*routine)(*format++, outarg); */
  114.  
  115. #ifdef DOEMOUTPUT
  116.         if (*format == LF && routine == vt100)
  117.             /* add CR to LF for emulator */
  118.             (*routine)(CR);
  119.  
  120. #endif
  121.         (*routine)(*format++);
  122.     }
  123.     if (*format == '\0')
  124.         return(0);
  125.  
  126.     format++;
  127.     if (*format == '0') 
  128.         l_zero = TRUE;
  129.     else 
  130.         l_zero = FALSE;
  131.     field = 0;
  132.     while (*format >= '0' && *format <= '9') {
  133.         field = field * 10 + *format - '0';
  134.         format++;
  135.     }
  136.     switch (*format) {
  137.     case 's':
  138.         s = *(char **)arg;
  139.         while (*s != '\0')
  140.             /* was (*routine)(*s++, outarg); */
  141.             (*routine)(*s++);
  142.         arg += 2;
  143.         break;
  144.     case 'c':
  145.         /* was (*routine)(*(char *)arg, outarg); */
  146.         (*routine)(*arg);
  147.         arg++;
  148.         break;
  149.     case '%':
  150.         /* was (*routine)('%', outarg); */
  151.         (*routine)('%');
  152.         arg++;
  153.         break;
  154.     case 'o':
  155.         int_print((unsigned long)*arg, 010, FALSE, field, l_zero, routine, outarg);
  156.         arg++;
  157.         break;
  158.     case 'O':
  159.         int_print(*(unsigned long *)arg, 010, FALSE, field, l_zero, routine, outarg);
  160.         arg += 2;
  161.         break;
  162.     case 'd':
  163.         int_print((long)*(int *)arg, 10, TRUE, field, l_zero, routine, outarg);
  164.         arg++;
  165.         break;
  166.     case 'D':
  167.         int_print(*(long *)arg, 10, TRUE, field, l_zero, routine, outarg);
  168.         arg += 2;
  169.         break;
  170.     case 'u':
  171.         int_print((unsigned long)*arg, 10, FALSE, field, l_zero, routine, outarg);
  172.         arg++;
  173.         break;
  174.     case 'U':
  175.         int_print(*(unsigned long *)arg, 10, FALSE, field, l_zero, routine, outarg);
  176.         arg += 2;
  177.         break;
  178.     case 'x':
  179.         int_print((unsigned long)*arg, 0x10, FALSE, field, l_zero, routine, outarg);
  180.         arg++;
  181.         break;
  182.     case 'X':
  183.         int_print(*(unsigned long *)arg, 0x10, FALSE, field, l_zero, routine, outarg);
  184.         arg += 2;
  185.         break;
  186.  
  187. #define    mkbyte(x)    (((unsigned)(x))&0xff)
  188.     case 'a': {
  189.         union {
  190.             long _l;
  191.             char _c[4];
  192.         } foo;
  193.  
  194.         foo._l = *(long *)arg;
  195.         arg += 2;
  196.  
  197.         _pr_ip(routine, outarg, "%d.%d.%d.%d",
  198.             mkbyte(foo._c[0]), mkbyte(foo._c[1]),
  199.             mkbyte(foo._c[2]), mkbyte(foo._c[3]));
  200.  
  201.         }
  202.         break;
  203.     case 'A': {
  204.         union {
  205.             long _l;
  206.             char _c[4];
  207.         } foo;
  208.  
  209.         foo._l = *(long *)arg;
  210.         arg += 2;
  211.  
  212.         _pr_ip(routine, outarg, "%o,%o,%o,%o",
  213.             mkbyte(foo._c[0]), mkbyte(foo._c[1]),
  214.             mkbyte(foo._c[2]), mkbyte(foo._c[3]));
  215.  
  216.         }
  217.         break;
  218.     }
  219.     format++;
  220.     goto    loop;
  221. }
  222.  
  223.  
  224. int_print(number, radix, hassign, field, l_zero, routine, outarg)
  225. unsigned long    number;    /* the number to print */
  226. int    radix;        /* the radix to print the number in */
  227. int    hassign;        /* true if should print as signed number */
  228. int    field;        /* the argument in the format control */
  229. int    l_zero;        /* true if arg had a leading zero */
  230. int    (*routine)();    /* routine to print out the number */
  231. int    outarg;        /* an argument to pass to the output routine */
  232. {
  233.     char    table[20];    /* place to make up the output */
  234.     int    negative;    /* true if number is signed and negative */
  235.     int    i;
  236.     char    c;
  237.     
  238.     if (hassign && ((long)number < 0)) {
  239.         negative = TRUE;
  240.         number = -(long)number;
  241.     }
  242.     else    negative = FALSE;
  243.     
  244.     c = l_zero ? '0' : ' ';
  245.     for (i=0; i < 20; i++)
  246.         table[i] = c;
  247.     
  248.     for (i = 0; i < 20; i++) {
  249.         table[i] = "0123456789ABCDEF"[number % (long)radix];
  250.         number /= (long)radix;
  251.         if (number == 0) break;
  252.     }
  253.     
  254.     if (negative) table[++i] = '-';
  255.     if ((field != 0) && (field < 20)) i = field - 1;
  256.     while (i >= 0)
  257.         /* was (*routine)(table[i--], outarg); */
  258.         (*routine)(table[i--]);
  259. }
  260.  
  261. _pr_ip(routine, outarg, format)
  262.     char *outarg;
  263.     int (*routine)();
  264.     char *format; 
  265. {
  266.  
  267.     _format_string(routine, outarg, &format);
  268. }
  269.